package com.example.demo.service.impl;

import com.example.demo.entity.GoodsSkusCombinations;
import com.example.demo.entity.GoodsSkus;
import com.example.demo.entity.GoodsSkusValue;
import com.example.demo.exception.BusinessException;
import com.example.demo.exception.ErrorCode;
import com.example.demo.mapper.GoodsSkusCombinationsMapper;
import com.example.demo.mapper.GoodsSkusMapper;
import com.example.demo.mapper.GoodsSkusValueMapper;
import com.example.demo.service.GoodsSkusCombinationsService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class GoodsSkusCombinationsServiceImpl implements GoodsSkusCombinationsService {

    private static final Logger logger = LoggerFactory.getLogger(GoodsSkusCombinationsServiceImpl.class);

    @Autowired
    private GoodsSkusCombinationsMapper goodsSkuCombinationsMapper;

    @Autowired
    private GoodsSkusMapper goodsSkusMapper;

    @Autowired
    private GoodsSkusValueMapper goodsSkusValueMapper;

    /**
     * 创建商品规格组合信息
     *
     * @param goodsSkuCombinations 商品规格组合信息对象
     * @return 返回创建后的商品规格组合信息对象
     */
    @Override
    public GoodsSkusCombinations createGoodsSkuCombinations(GoodsSkusCombinations goodsSkuCombinations) {
        goodsSkuCombinationsMapper.insert(goodsSkuCombinations);
        logger.info("创建商品规格信息: {}", goodsSkuCombinations);
        return goodsSkuCombinations;
    }

    /**
     * 更新商品SKU组合信息
     *
     * @param goodsSkuCombinations 商品SKU组合对象
     * @return 更新成功返回true，否则返回false
     */
    @Override
    public boolean updateGoodsSkuCombinations(GoodsSkusCombinations goodsSkuCombinations) {
        GoodsSkusCombinations comb = goodsSkuCombinationsMapper.selectById(goodsSkuCombinations.getId());
        if (comb == null) {
            throw new BusinessException(ErrorCode.GOODS_SKUS_COMB_NOT_FOUND);
        }
        goodsSkuCombinationsMapper.updateById(goodsSkuCombinations);
        logger.info("更新商品规格信息: {}", goodsSkuCombinations);
        return true;
    }

    /**
     * 根据商品SKU组合ID删除商品SKU组合
     *
     * @param id 商品SKU组合ID
     * @return 如果删除成功返回true，否则返回false
     */
    @Override
    public boolean deleteGoodsSkuCombinations(Integer id) {
        GoodsSkusCombinations comb = goodsSkuCombinationsMapper.selectById(id);
        if (comb == null) {
            throw new BusinessException(ErrorCode.GOODS_SKUS_COMB_NOT_FOUND);
        }
        goodsSkuCombinationsMapper.deleteById(id);
        logger.info("删除商品规格信息: {}", id);
        return true;
    }

    /**
     * 根据商品ID获取该商品的SKU组合列表
     *
     * @param goods_id 商品ID
     * @return 返回该商品对应的SKU组合列表
     */
    @Override
    public List<GoodsSkusCombinations> getGoodsSkuCombinationsByGoodsId(Integer goods_id) {
        List<GoodsSkusCombinations> list = goodsSkuCombinationsMapper.selectByGoodsId(goods_id);
        logger.info("获取商品规格信息列表: {}", goods_id);
        return list;
    }

    /**
     * 通过ID获取商品SKU组合信息
     *
     * @param id 商品SKU组合ID
     * @return 返回对应的商品SKU组合对象
     */
    @Override
    public GoodsSkusCombinations getGoodsSkuCombinationsById(Integer id) {
        GoodsSkusCombinations g = goodsSkuCombinationsMapper.selectById(id);
        logger.info("获取商品规格信息: {}", id);
        return g;
    }

    /**
     * 根据商品ID设置商品SKU组合。
     *
     * @param goods_id 商品ID
     * @return 商品SKU组合列表
     */
    @Override
    @Transactional
    public List<GoodsSkusCombinations> setGoodsSkuCombinationsByGoodsId(Integer goods_id) {
        // 1. 查询出该商品在数据库中的原有商品组合列表
        List<GoodsSkusCombinations> originalCombinationsList = goodsSkuCombinationsMapper.selectByGoodsId(goods_id);

        // 2. 获取该商品的所有规格及其规格值
        List<GoodsSkus> goodsSkusList = goodsSkusMapper.selectByGoodsId(goods_id);
        List<List<GoodsSkusValue>> skuValuesList = new ArrayList<>();
        for (GoodsSkus sku : goodsSkusList) {
            List<GoodsSkusValue> values = goodsSkusValueMapper.selectBySkuId(sku.getId());
            skuValuesList.add(values);
        }

        // 3. 生成所有可能的规格组合
        List<GoodsSkusCombinations> newCombinationsList = generateCombinations(goods_id, goodsSkusList, skuValuesList);

        // 4. 比较新旧组合列表，进行更新、新增或删除操作
        for (GoodsSkusCombinations newCombination : newCombinationsList) {
            boolean exists = false;
            for (GoodsSkusCombinations originalCombination : originalCombinationsList) {
                if (isSameCombination(newCombination.getSku_combination(), originalCombination.getSku_combination())) {
                    // 如果组合已存在，则更新
                    originalCombination.setSku_combination(newCombination.getSku_combination());
                    originalCombination.setSku_combination_name(newCombination.getSku_combination_name());
                    originalCombination.setOrder(newCombination.getOrder());
                    goodsSkuCombinationsMapper.updateById(originalCombination);
                    exists = true;
                    break;
                }
            }
            if (!exists) {
                // 如果组合不存在，则新增
                goodsSkuCombinationsMapper.insert(newCombination);
            }
        }

        // 5. 删除不再需要的组合
        for (GoodsSkusCombinations originalCombination : originalCombinationsList) {
            boolean found = false;
            for (GoodsSkusCombinations newCombination : newCombinationsList) {
                if (isSameCombination(originalCombination.getSku_combination(), newCombination.getSku_combination())) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                goodsSkuCombinationsMapper.deleteById(originalCombination.getId());
            }
        }

        List<GoodsSkusCombinations> result = getGoodsSkuCombinationsByGoodsId(goods_id);
        logger.info("设置商品规格信息: {}", goods_id);
        return result;
    }

    /**
     * 生成商品SKU组合列表
     *
     * @param goods_id 商品ID
     * @param goodsSkusList 商品SKU列表
     * @param skuValuesList 商品SKU值列表
     * @return 商品SKU组合列表
     */
    private List<GoodsSkusCombinations> generateCombinations(Integer goods_id, List<GoodsSkus> goodsSkusList, List<List<GoodsSkusValue>> skuValuesList) {
        List<GoodsSkusCombinations> combinations = new ArrayList<>();
        generateCombinationsRecursive(goods_id, goodsSkusList, skuValuesList, 0, new ArrayList<>(), new ArrayList<>(), combinations);
        return combinations;
    }

    /**
     * 递归生成商品SKU组合
     *
     * @param goods_id 商品ID
     * @param goodsSkusList 商品SKU列表
     * @param skuValuesList SKU值列表
     * @param depth 当前递归深度
     * @param currentCombination 当前组合
     * @param currentCombinationName 当前组合名字
     * @param combinations 组合列表
     */
    private void generateCombinationsRecursive(Integer goods_id, List<GoodsSkus> goodsSkusList, 
    List<List<GoodsSkusValue>> skuValuesList, int depth, List<String> currentCombination, List<String> currentCombinationName,
    List<GoodsSkusCombinations> combinations) {
        if (depth == goodsSkusList.size()) {
            GoodsSkusCombinations combination = new GoodsSkusCombinations();
            combination.setGoods_id(goods_id);
            combination.setSku_combination(String.join(",", currentCombination));
            combination.setSku_combination_name(String.join(",", currentCombinationName));
            combination.setOrder(combinations.size() + 1);
            combination.setOriginal_price(0);
            combination.setSale_price(0);
            combination.setCost_price(0);
            combination.setStock(0);
            combinations.add(combination);
            return;
        }

        GoodsSkus sku = goodsSkusList.get(depth);
        List<GoodsSkusValue> values = skuValuesList.get(depth);
        for (GoodsSkusValue value : values) {
            List<String> newCombination = new ArrayList<>(currentCombination);
            List<String> newCombinationName = new ArrayList<>(currentCombinationName);
            newCombination.add(sku.getId() + ":" + value.getId());
            newCombinationName.add(sku.getName()+ ":" + value.getValue());
            generateCombinationsRecursive(goods_id, goodsSkusList, skuValuesList, depth + 1, newCombination, newCombinationName, combinations);
        }
    }

    /**
     * 判断两个字符串组合是否相同。
     *
     * @param combination1 第一个组合字符串，以逗号分隔
     * @param combination2 第二个组合字符串，以逗号分隔
     * @return 如果两个组合字符串相同，则返回true；否则返回false
     */
    private boolean isSameCombination(String combination1, String combination2) {
        String[] parts1 = combination1.split(",");
        String[] parts2 = combination2.split(",");
        Arrays.sort(parts1);
        Arrays.sort(parts2);
        return Arrays.equals(parts1, parts2);
    }
}
